﻿using System;
using System.Linq;
using System.Xml.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq.Expressions;

namespace CodeCounsel.SharePoint.RibbonDesigner.Model
{
    public static class XExtensions
    {
        public static void AddRange<T>(this Collection<T> collection, params T[] items)
            where T : DomainElement
        {
            if (items != null)
            {
                foreach (T item in items)
                {
                    collection.Add(item);
                }
            }
        }

        public static void SetAttributeValue<T>(this XElement element, XName attributeName, T value)
        {
            XAttribute attribute = element.Attributes(attributeName).FirstOrDefault();
            if (attribute == null)
            {
                attribute = new XAttribute(attributeName, value);
            }
            else
            {
                attribute.Value = Convert.ToString(value);
            }
        }

        public static void SetAttributeValue(this XElement element, XName attributeName, string value)
        {
            XAttribute attribute = element.Attributes(attributeName).FirstOrDefault();
            if (attribute == null)
            {
                attribute = new XAttribute(attributeName, value);
            }
            else
            {
                attribute.Value = value;
            }
        }

        public static T GetAttributeValue<T>(
            this XElement element, 
            Expression<Func<T>> selector)
        {
            return GetAttributeValue(element, selector, default(T));
        }

        public static T GetAttributeValue<T>(
            this XElement element,
            Expression<Func<T>> selector, 
            T defaultValue)
        {
            MemberExpression expression = (MemberExpression)selector.Body;
            XNameAttribute xname = (XNameAttribute)Attribute.GetCustomAttribute(expression.Member, typeof(XNameAttribute));
            return GetAttributeValue(element, xname.ToName(), defaultValue);
        }


        public static string GetAttributeValue(this XElement element, XName attributeName)
        {
            return GetAttributeValue(element, attributeName, null);
        }

        public static string GetAttributeValue(this XElement element, XName attributeName, string defaultValue)
        {
            XAttribute attribute = element.Attributes(attributeName).FirstOrDefault();
            return attribute != null ? attribute.Value : defaultValue;
        }

        public static T GetAttributeValue<T>(this XElement element, XName attributeName)
        {
            return GetAttributeValue<T>(element, attributeName, default(T));
        }

        public static T GetAttributeValue<T>(this XElement element, XName attributeName, T defaultValue)
        {
            T result = defaultValue;
            XAttribute attribute = element.Attributes(attributeName).FirstOrDefault();
            TypeConverter converter = null;
            TypeConverterAttribute converterAttribute = (TypeConverterAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TypeConverterAttribute));
            if (converterAttribute != null)
            {
                converter = (TypeConverter)Activator.CreateInstance(Type.GetType(converterAttribute.ConverterTypeName));
            }
            else
            {
                converter = TypeDescriptor.GetConverter(typeof(T));
            }
            if (attribute != null && converter.CanConvertFrom(typeof(string)) && String.IsNullOrEmpty(attribute.Value) == false)
            {
                result = (T)converter.ConvertFrom(attribute.Value);
            }
            return result;
        }
    }

}
